const cvs = document.getElementById('canvas');
const cvsHandler = document.getElementById('canvas-handle');
const fileUpload = document.getElementById('imageUpload');
const ctx = cvs && cvs.getContext('2d', { willReadFrequently: true });
const ctxHandler = cvsHandler && cvsHandler.getContext('2d', { willReadFrequently: true });
const picker = document.getElementById('picker');
const generateBtn = document.getElementById('generate');

cvs.width = cvsHandler.width = cvs.parentNode.clientWidth;
cvs.height = cvsHandler.height = cvs.parentNode.clientHeight;

let url = '';
let clickColor = [];

fileUpload.addEventListener('change', function (e) {
  const file = e.target.files[0];
  url = URL.createObjectURL(file);
  // 清空画布,不然图片会重叠
  ctx.clearRect(0, 0, cvs.width, cvs.height);
  ctxHandler.clearRect(0, 0, cvs.width, cvs.height);
  init();
});

function init() {
  const image = new Image();
  image.src = url;
  image.onload = function () {
    //图片缩放比例,小图片放大,大图片缩小
    let scale = image.width / cvs.width;
    //图片居中处理
    let x = image.width / scale >= cvs.width ? 0 : (cvs.width - image.width / scale) / 2;
    let y = image.height / scale >= cvs.height ? 0 : (cvs.height - image.height / scale) / 2;

    ctx.drawImage(image, 0, 0, image.width, image.height, x, y, image.width / scale, image.height / scale);
    ctxHandler.drawImage(image, 0, 0, image.width, image.height, x, y, image.width / scale, image.height / scale);
  };
}

/**
 * @desc 根据x,y返回imageData里面对应的颜色值
 * @param { Number } x
 * @param { Number } y
 * @returns {Number} index 点击的位置索引
 */
function point2Index(x, y) {
  return (y * cvs.width + x) * 4;
}

/**
 * @desc 通过索引获取点击点的颜色数值
 * @param {boolean} a
 */
function getColorByIndex(index, imageData) {
  const r = imageData.data[index];
  const g = imageData.data[index + 1];
  const b = imageData.data[index + 2];
  const a = imageData.data[index + 3];
  return [r, g, b, a];
}

/**
 * @desc 修改相近的imageData item 数据,
 * @param { Array } clickColor
 * @param { Array } toChangeColorToRgba
 * @param { Object } imageData
 * @returns { Object } new imageData object
 */
function getImageData(clickColor, toChangeColorToRgba, imageData) {
  const data = imageData.data || [];

  for (let i = 0, len = data.length; i < len; i += 4) {
    const isSim = isSimilar(clickColor, data.slice(i, i + 4), 30);
    if (isSim) {
      data[i] = toChangeColorToRgba[0];
      data[i + 1] = toChangeColorToRgba[1];
      data[i + 2] = toChangeColorToRgba[2];
      data[i + 3] = toChangeColorToRgba[3];
    }
  }

  return imageData;
}

/**
 * @desc 十六进制转rgba
 * @param {string} hex
 * @returns {boolean} 返回值为true
 */
function hexToRgba(hex, opacity = 255) {
  hex = hex.replace('#', '');
  let r = parseInt(hex.substring(0, 2), 16);
  let g = parseInt(hex.substring(2, 4), 16);
  let b = parseInt(hex.substring(4, 6), 16);

  return [r, g, b, opacity];
}

/**
 * @desc
 * @param {Arrary} color1
 * @param {Arrary} color2
 * @param {Number} difference 差值
 * @returns {boolean} return boolean
 */
function isSimilar(color1, color2, difference) {
  let diff = Math.abs(color1[0] - color2[0]) + Math.abs(color1[1] - color2[1]) + Math.abs(color1[2] - color2[2]) + Math.abs(color1[3] - color2[3]);
  return diff < difference;
}

generateBtn.addEventListener('click', function () {
  if (!clickColor.length) return;
  const imageData = ctx.getImageData(0, 0, cvs.width, cvs.height);
  const toChangeColorToRgba = hexToRgba(picker.value);
  const newImageData = getImageData(clickColor, toChangeColorToRgba, imageData);

  ctxHandler.putImageData(newImageData, 0, 0);
});

cvs.addEventListener('click', function (e) {
  if (!url) return;
  const x = e.offsetX;
  const y = e.offsetY;
  const imageData = ctx.getImageData(0, 0, cvs.width, cvs.height);
  const index = point2Index(x, y);
  clickColor = getColorByIndex(index, imageData);
});
